<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>[4.3]-开发实战3：一个简单的小型项目开发（奔跑吧兄弟投票活动） | PhalApi(π框架) - PHP轻量级开源接口框架 - 助你创造价值！</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <meta content="yes" name="apple-mobile-web-app-capable">
    <meta content="black" name="apple-mobile-web-app-status-bar-style">
    <meta content="telephone=no" name="format-detection">
    <meta content="email=no" name="format-detection">
    <meta name="Author" content="PhalApi,ecitlm,dogstar">
    <meta name="description" content="[4.3]-开发实战3：一个简单的小型项目开发（奔跑吧兄弟投票活动），PhalApi是一个PHP轻量级开源接口框架，致力于快速开发接口服务。支持HTTP/SOAP/RPC等协议，可用于搭建接口/微服务/RESTful接口/Web Services。我们不断更新，保持生气；为接口负责，为开源负责！并承诺永久免费！">
    <meta name="keywords" content="PhalApi,phalapi,phalapi接口开发,后台接口开发,后台接口开发框架,接口开发,接口框架,开源接口框架,PHP后台接口开发,PHP接口开发,PHP接口框架,PHP后台接口框架,phalapi官网,PHP接口框架,php接口开发框架,php接口开发,php web框架,π框架,π开发框架,π接口框架,π接口开发框架,api接口,php接口,,PHP接口框架,phalapi文档,phalapi wiki,PhalApi文档,phalapi在线文档,phalapi官方文档">

    <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" media="screen">
    <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.css" media="screen">
    <link rel="stylesheet" href="../css/main.css" />
    <link rel="stylesheet" href="../css/loading_bar.css" />
    <link rel="icon" href="http://webtools.qiniudn.com/dog_catch.png" type="image/x-icon" />
    <script src="../js/pace.min.js"></script>
	
	<!-- 代码高亮 -->
	<link rel="stylesheet" href="../css/highlight.min.css">
	<script src="../js/highlight.min.js"></script>
	<script>hljs.initHighlightingOnLoad();</script>
    
</head>

<body>
    <!-- navbar start -->
    <div class="navbar navbar-default navbar-fixed-top" id="mainnav" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand website_name" href="/"><!-- <span>PhalApi</span> --><strong>PhalApi</strong></a>
            </div>
            <div class="navbar-collapse collapse" aria-expanded="false" style="height: 1px;">
                <ul class="nav navbar-nav navbar-right" id="nav_bar">
                    <li><a href="/"><span class="glyphicon glyphicon-home"></span></a></li>
                    <li><a href="http://qa.phalapi.net/">社区</a></li>
                    <li><a href="/download.html">下载</a></li>
                    <li class="active"><a href="/wikis/">文档</a></li>
                    <li><a href="http://www.ituring.com.cn/book/2405">书籍</a></li>
                    <li><a href="http://demo.phalapi.net/">体验</a></li>
                    <li><a href="/about.html">关于</a></li>
                    <li><a href="/donate.html">贡献</a></li>
                    <li><a href="/wikis/en/">English</a></li>
                </ul>
            </div>
            <!--/.nav-collapse -->
        </div>
    </div>
    <!-- navbar end -->


    <div id="content">
        <div class="container">
            <div class="row row-md-flex row-md-flex-wrap">
                <h4><a href="/wikis/%5B4.2%5D-%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%982%EF%BC%9A%E6%A8%A1%E6%8B%9F%E4%BC%98%E9%85%B7%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0%E6%8E%A5%E5%8F%A3%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91.html">上一章</a>   <a href="/wikis/">文档首页</a>   <a href="#">下一章</a></h4>
<hr />
<p><em>Give it some time, everything will be okay.  -- 《那些年我们疯狂的青春/青春洋溢色彩/This Youth is Crazy》</em></p>
<h2>4.3.1 模拟的业务场景</h2>
<p>假设我们需要为“奔跑吧兄弟”综艺节目开发一套手机App的投票接口，以供用户在观看电视的同时，可以进行投票活动参与互动。  </p>
<p>下面将以此模拟的业务场景，提供一个接口开发实战的过程。  </p>
<h2>4.3.2 源代码下载</h2>
<p><a href="http://git.oschina.net/dogstar/PhalApi-Demo-Vote">PhalApi-Demo-Vote</a>  </p>
<h2>4.3.3 接口总列表</h2>
<p>以下是我们根据业务需求整理出来的接口：</p>
<ul>
<li>1、用户可以通过微信、QQ、新浪微博等渠道进行第三方登录</li>
<li>2、用户可以创建团队进行参赛，但队名不能重复</li>
<li>3、用户可以对已参赛的团队进行投票，且每个用户每天投票最多不能超过3次，支持可配置</li>
<li>4、获取已参赛团队的得票排行榜</li>
</ul>
<h2>4.3.4 主要涉及技术功能点</h2>
<ul>
<li>1、使用User扩展类库实现第三方登录操作</li>
<li>2、使用缓存存放用户每天投票的次数（为方便起见，使用文件缓存，不落地）</li>
<li>3、对接口进行签名验证（为方便起见，固定sign签名）</li>
<li>4、数据库的基本操作</li>
<li>5、自动化脚本的使用</li>
</ul>
<h2>4.3.4 快速开发流程</h2>
<p>（题外音：整个示例的开发，我个人在单元测试驱动开发下，只用了两个多小时，其中还包括对模板场景的业务构思、建表、编写单元测试代码等）。  </p>
<h3>(1)创建项目和部署环境</h3>
<p>把PhalApi最新的框架代码下载后，并将User扩展类库按文档说明配置后，将项目部署到了以下接口域名：</p>
<pre><code>http://api.vote.phalapi.com</code></pre>
<p>测试一下：</p>
<pre><code class="language-php">http://api.vote.phalapi.com/vote/?sign=phalapi

//返回
{
    "ret": 200,
    "data": {
        "title": "Hello World!",
        "content": "PHPer您好，欢迎使用PhalApi！",
        "version": "1.1.4",
        "time": 1431796924
    },
    "msg": ""
}</code></pre>
<p>Good! 下面是简明的开发过程。</p>
<h3>(2)单元测试驱动开发</h3>
<p>在定好接口后：</p>
<pre><code class="language-php">&lt;?php
class Api_Act extends PhalApi_Api {

    public function joinIn() {
    }

    public function showList() {
    }

    public function vote() {
    }
}</code></pre>
<p>便可使用脚本，快速生成单元测试的骨架代码：</p>
<pre><code class="language-php">$ cd ./Vote/Tests/Api
$ phalapi_buildtests ../../Api/Act.php Api_Act ../test_env.php  &gt; Api_Act_Test.php</code></pre>
<h3>(3)快速开发</h3>
<p>开发过程此处略，但在单元测试驱动的引导下，很快就产出了以下高质量的代码：</p>
<pre><code class="language-php">.
├── Api
│   ├── Act.php
│   └── Default.php
├── Common
│   └── SignFilter.php
├── Domain
│   ├── Team.php
│   └── Vote.php
├── Model
│   ├── Team.php
│   ├── UserVoteRecord.php
│   └── Vote.php
└── Tests
    ├── Api
    │   ├── Api_Act_Test.php
    │   └── Api_Default_Test.php
    ├── Domain
    ├── Model
    ├── phpunit.xml
    └── test_env.php
</code></pre>
<h3>(4)单元测试全部通过了！</h3>
<p>为了方便大家查看，已省略了部分的调试内容，但保留了测试过程中全部执行的SQL语句，如下：</p>
<pre><code class="language-php">$ phpunit ./Api_Act_Test.php 
PHPUnit 4.3.4 by Sebastian Bergmann.

[1 - 0.06911s]DELETE FROM phalapi_team WHERE (team_name = 'test team name');&lt;br&gt;
[2 - 0.06487s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');&lt;br&gt;
[3 - 0.06553s]SELECT COUNT(id) FROM phalapi_team WHERE (team_name = 'test team name');&lt;br&gt;
[4 - 0.0653s]INSERT INTO phalapi_team (team_name) VALUES ('test team name');&lt;br&gt;
[5 - 0.0699s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');&lt;br&gt;
[6 - 0.06555s]SELECT COUNT(id) FROM phalapi_team WHERE (team_name = 'test team name');&lt;br&gt;
[9 - 0.06778s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');&lt;br&gt;
[10 - 0.06603s]SELECT COUNT(id) FROM phalapi_team WHERE (id = 3);&lt;br&gt;
[11 - 0.06825s]SELECT vote_num FROM phalapi_vote WHERE (team_id = 3) LIMIT 1;&lt;br&gt;
[12 - 0.07374s]UPDATE phalapi_vote SET team_id = 3, vote_num = 22 WHERE (team_id = 3);&lt;br&gt;
[13 - 0.07012s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');&lt;br&gt;
[14 - 0.06682s]SELECT COUNT(id) FROM phalapi_team WHERE (id = 3);&lt;br&gt;
[15 - 0.07433s]SELECT vote_num FROM phalapi_vote WHERE (team_id = 3) LIMIT 1;&lt;br&gt;
[16 - 0.07283s]UPDATE phalapi_vote SET team_id = 3, vote_num = 23 WHERE (team_id = 3);&lt;br&gt;
[17 - 0.07307s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');&lt;br&gt;
[18 - 0.07501s]SELECT COUNT(id) FROM phalapi_team WHERE (id = 3);&lt;br&gt;
[19 - 0.07135s]SELECT vote_num FROM phalapi_vote WHERE (team_id = 3) LIMIT 1;&lt;br&gt;
[20 - 0.07653s]UPDATE phalapi_vote SET team_id = 3, vote_num = 24 WHERE (team_id = 3);&lt;br&gt;
[21 - 0.07215s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');&lt;br&gt;
[22 - 0.06722s]SELECT COUNT(id) FROM phalapi_team WHERE (id = 3);&lt;br&gt;
[23 - 0.06506s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');&lt;br&gt;
[24 - 0.06732s]SELECT COUNT(id) FROM phalapi_team WHERE (id = 404);&lt;br&gt;

Time: 1.97 seconds, Memory: 7.00Mb

OK (4 tests, 42 assertions)</code></pre>
<h3>(5)运行效果 - Part 1</h3>
<p>在我们通过第三方登录后，我们就可以这样进行接口操作了。  </p>
<p>首先，让我们添加两个参赛团队：</p>
<pre><code class="language-php">//奔跑吧兄弟（蓝队）
http://api.vote.phalapi.com/vote/?sign=phalapi&amp;service=Act.JoinIn&amp;team_name=%E5%A5%94%E8%B7%91%E5%90%A7%E5%85%84%E5%BC%9F%EF%BC%88%E8%93%9D%E9%98%9F%EF%BC%89&amp;token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&amp;user_id=1
//返回
{
    "ret": 200,
    "data": {
        "code": 0,
        "team_id": "5"
    },
    "msg": ""
}

//奔跑吧兄弟（红队）
http://api.vote.phalapi.com/vote/?sign=phalapi&amp;service=Act.JoinIn&amp;team_name=%E5%A5%94%E8%B7%91%E5%90%A7%E5%85%84%E5%BC%9F%EF%BC%88%E7%BA%A2%E9%98%9F%EF%BC%89&amp;token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&amp;user_id=1
//返回
{
    "ret": 200,
    "data": {
        "code": 0,
        "team_id": "6"
    },
    "msg": ""
}</code></pre>
<p>然后，让我们进行疯狂地投票：</p>
<pre><code class="language-php">//第一次投票
http://api.vote.phalapi.com/vote/?sign=phalapi&amp;service=Act.Vote&amp;team_id=5&amp;token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&amp;user_id=1
//返回
{"ret":200,"data":{"code":0,"vote_num":1},"msg":""}

//第二次投票
http://api.vote.phalapi.com/vote/?sign=phalapi&amp;service=Act.Vote&amp;team_id=5&amp;token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&amp;user_id=1
//返回
{"ret":200,"data":{"code":0,"vote_num":2},"msg":""}

//第三次投票
http://api.vote.phalapi.com/vote/?sign=phalapi&amp;service=Act.Vote&amp;team_id=5&amp;token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&amp;user_id=1
//返回
{"ret":200,"data":{"code":0,"vote_num":3},"msg":""}

//第四次投票
http://api.vote.phalapi.com/vote/?sign=phalapi&amp;service=Act.Vote&amp;team_id=5&amp;token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&amp;user_id=1
//返回 - 注意此返回！
{"ret":200,"data":{"code":2,"vote_num":0},"msg":""}</code></pre>
<p>最后，看一下排行榜：</p>
<pre><code class="language-php">http://api.vote.phalapi.com/vote/?sign=phalapi&amp;service=Act.ShowList&amp;token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&amp;user_id=1
//返回
{
    "ret": 200,
    "data": {
        "code": 0,
        "teams": [
            {
                "id": 5,
                "team_name": "奔跑吧兄弟（蓝队）",
                "vote_num": 3
            },
            {
                "id": 6,
                "team_name": "奔跑吧兄弟（红队）",
                "vote_num": 0
            }
        ]
    },
    "msg": ""
}</code></pre>
<p>至此，我们已经可以把接口交付给客户端同学使用啦！<br />
当然，我们还需要稍微整理输出WIKI文档~~~<br />
部分接口返回的结果可能与你实际看到的不一样，因为数据会在变化而且有单元测试的测试数据。  </p>
<h3>(6)运行效果 - Part 2</h3>
<p>接口服务，不仅仅需要提供正常的业务功能，还需要考虑到各种客户端使用的情况，包括非法的请求，或者不合的调用，比如防刷票。  </p>
<p>这一部分，主要展示接口在各种异常情况下的响应能力。  </p>
<h4>签名失败</h4>
<pre><code class="language-php">http://api.vote.phalapi.com/vote/?sign=XXX&amp;service=Act.JoinIn&amp;team_name=%E5%A5%94%E8%B7%91%E5%90%A7%E5%85%84%E5%BC%9F%EF%BC%88%E7%BA%A2%E9%98%9F%EF%BC%89&amp;token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&amp;user_id=1
//返回
{
    "ret": 400,
    "data": [
    ],
    "msg": "非法请求：wrong sign"
}</code></pre>
<h4>无登录态</h4>
<pre><code class="language-php">http://api.vote.phalapi.com/vote/?sign=phalapi&amp;service=Act.JoinIn&amp;team_name=%E5%A5%94%E8%B7%91%E5%90%A7%E5%85%84%E5%BC%9F%EF%BC%88%E7%BA%A2%E9%98%9F%EF%BC%89&amp;token=XXX&amp;user_id=1
//返回
{
    "ret": 401,
    "data": [
    ],
    "msg": "非法请求：user need to login again"
}</code></pre>
<h4>重复参赛</h4>
<pre><code class="language-php">http://api.vote.phalapi.com/vote/?sign=phalapi&amp;service=Act.JoinIn&amp;team_name=%E5%A5%94%E8%B7%91%E5%90%A7%E5%85%84%E5%BC%9F%EF%BC%88%E7%BA%A2%E9%98%9F%EF%BC%89&amp;token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&amp;user_id=1
//返回
{
    "ret": 200,
    "data": {
        "code": 1,
        "team_id": 0
    },
    "msg": ""
}</code></pre>
<h4>当天投票次数已达最大</h4>
<pre><code class="language-php">//第四次投票后
http://api.vote.phalapi.com/vote/?sign=phalapi&amp;service=Act.Vote&amp;team_id=5&amp;token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&amp;user_id=1
//返回 - 注意此返回！
{
    "ret": 200,
    "data": {
        "code": 2,
        "vote_num": 0
    },
    "msg": ""
}</code></pre>
<h4>投票的团队不存在</h4>
<pre><code class="language-php">http://api.vote.phalapi.com/vote/?sign=phalapi&amp;service=Act.Vote&amp;team_id=404&amp;token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&amp;user_id=1
//返回
{
    "ret": 200,
    "data": {
        "code": 1,
        "vote_num": 0
    },
    "msg": ""
}</code></pre>
<p>在进行上面的非法请求后，我们可以同时关注后台的日记：</p>
<pre><code class="language-php">$ tailf ./Runtime/log/201505/20150517.log 
2015-05-17 01:35:32|DEBUG|user not login|{"userId":null,"token":null}
2015-05-17 01:36:01|DEBUG|user can not vote today|{"userId":1,"teamId":5}
2015-05-17 01:37:52|DEBUG|user can not vote today|{"userId":1,"teamId":5}
2015-05-17 01:45:25|DEBUG|user need to login again|{"expiresTime":0,"userId":"1","token":"XXX"}
2015-05-17 01:48:13|DEBUG|user can not vote today|{"userId":1,"teamId":5}</code></pre>
<h3>(7)需要的数据库表</h3>
<p>以下为关键的表，其他表，可以通过脚本自动生成，然后导入。</p>
<pre><code class="language-php">-- ----------------------------
-- Table structure for `phalapi_team`
-- ----------------------------
DROP TABLE IF EXISTS `phalapi_team`;
CREATE TABLE `phalapi_team` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `team_name` varchar(100) DEFAULT '' COMMENT '队名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of phalapi_team
-- ----------------------------
INSERT INTO `phalapi_team` VALUES ('3', 'egg team');
INSERT INTO `phalapi_team` VALUES ('5', '奔跑吧兄弟（蓝队）');
INSERT INTO `phalapi_team` VALUES ('6', '奔跑吧兄弟（红队）');
INSERT INTO `phalapi_team` VALUES ('17', 'test team name');

INSERT INTO `phalapi_user` VALUES ('1', 'wx_edebc877070133c65161d00799e00544', 'weixinName', '******', '4CHqOhe1Jxi3X9HmRfPOXygDnU267eCA', '1431790647', 'phpunit.png');

INSERT INTO `phalapi_user_login_weixin` VALUES ('1', 'wx_122348561111', 'ASDF', '130000000', '1');

INSERT INTO `phalapi_user_session_1` VALUES ('1', '1', '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731', '', '1', '1431790647', '1934382647', null);</code></pre>
<h2>4.3.4 脚本的使用</h2>
<h3>(1)创建项目脚本 - phalapi_buildapp</h3>
<p>此脚本可用于快速创建项目，其使用如下：</p>
<pre><code class="language-php">$ ./PhalApi/phalapi-buildapp 
Usage: ./PhalApi/phalapi-buildapp &lt;app&gt;</code></pre>
<p>此脚本会根据Demo示例，快速生成一个新的项目。</p>
<h3>(2)自动生成单元测试骨架脚本 - phalapi_buildtest</h3>
<p>这是一个用来自动生成单元测试骨架的脚本，其使用如下：</p>
<pre><code class="language-php">$ phalapi-buildtest 

Usage: 
        php /usr/bin/phalapi-buildtest &lt;file_path&gt; &lt;class_name&gt; [bootstrap] [author = dogstar]

Demo:
        php ./build_phpunit_test_tpl.php ./Demo.php Demo &gt; Demo_Test.php</code></pre>
<p>然后，我们就可以使用辅助的PhalApi_Helper_TestRunner::go()进行单元测试：</p>
<pre><code class="language-php">    public function testShowList()
    {
        //Step 1. 构建请求URL
        $url = 'service=Act.ShowList&amp;sign=phalapi&amp;user_id=1&amp;token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731';

        //Step 2. 执行请求  
        $rs = PhalApiTestRunner::go($url);
        //var_dump($rs);

        //Step 3. 验证
        $this-&gt;assertNotEmpty($rs);
        $this-&gt;assertArrayHasKey('code', $rs);
        $this-&gt;assertArrayHasKey('teams', $rs);
        $this-&gt;assertEquals(0, $rs['code']);

        $this-&gt;assertNotEmpty($rs['teams']);
        foreach ($rs['teams'] as $team) {
            $this-&gt;assertArrayHasKey('id', $team);
            $this-&gt;assertArrayHasKey('team_name', $team);
            $this-&gt;assertArrayHasKey('vote_num', $team);

            $this-&gt;assertGreaterThanOrEqual(0, $team['vote_num']);
        }
    }</code></pre>
<h3>(3)自动生成分表建表SQL语句 - phalapi_buildsqls</h3>
<p>此脚本用于根据dbs.php配置和./Data/*.sql文件生成完整的建表语句，其使用如下：</p>
<pre><code class="language-php">$ ./PhalApi/phalapi-buildsqls 
Usage: ./PhalApi/phalapi-buildsqls &lt;dbs.php&gt; &lt;table&gt; [engine=InnoDB]</code></pre>
<p>假设我们需要对vote进行分表，拆分成3个表，可以这样配置：</p>
<pre><code class="language-php">//$ vim ./Config/dbs.php

        'vote' =&gt; array(
            'prefix' =&gt; 'phalapi_',
            'key' =&gt; 'id',
            'map' =&gt; array(
                array('start' =&gt; 0, 'end' =&gt; 2, 'db' =&gt; 'db_vote'),
            ),
        ),</code></pre>
<p>然后准备基本的建表语句：</p>
<pre><code class="language-php">//$vim ./Data/vote.sql

  `team_id` bigint(20) DEFAULT '0',
  `vote_num` int(11) DEFAULT '0',</code></pre>
<p>最后，执行生成脚本：</p>
<pre><code class="language-php">$ phalapi-buildsqls ./Config/dbs.php vote

/**
 * DB: phalapi_vote
 */

CREATE TABLE `phalapi_vote_0` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
    `team_id` bigint(20) DEFAULT '0',
  `vote_num` int(11) DEFAULT '0',
    `ext_data` text COMMENT 'json data here',
     PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `phalapi_vote_1` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
    `team_id` bigint(20) DEFAULT '0',
  `vote_num` int(11) DEFAULT '0',
    `ext_data` text COMMENT 'json data here',
     PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `phalapi_vote_2` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
    `team_id` bigint(20) DEFAULT '0',
  `vote_num` int(11) DEFAULT '0',
    `ext_data` text COMMENT 'json data here',
     PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
</code></pre>
<h2>4.3.5 在线接口参数查看</h2>
<p>可以通过以下链接，在线实时查看接口参数：</p>
<pre><code class="language-php">//参赛接口
http://api.vote.phalapi.com/vote/checkApiParams.php?service=Act.JoinIn

//投票接口
http://api.vote.phalapi.com/vote/checkApiParams.php?service=Act.Vote

//排行榜接口
http://api.vote.phalapi.com/vote/checkApiParams.php?service=Act.ShowList</code></pre>
<p>其中，投票接口的参数如下：<br />
<img src="http://webtools.qiniudn.com/20150517.jpg" alt="a pic" />  </p>
<hr />
<h4><a href="/wikis/%5B4.2%5D-%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%982%EF%BC%9A%E6%A8%A1%E6%8B%9F%E4%BC%98%E9%85%B7%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0%E6%8E%A5%E5%8F%A3%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91.html">上一章</a>   <a href="/wikis/">文档首页</a>   <a href="#">下一章</a></h4><div style="float: left">
<h4>
<a href="http://qa.phalapi.net/">还有疑问？欢迎到社区提问！</a>
</h4>
</div>
            </div>
        </div>
    </div>

 <!-- 广告位 -->
<div class="grid-wrapper desktop-only">
	<p align="center">
		<a href="http://7xiz2f.com1.z0.glb.clouddn.com/%E6%88%91%E7%9A%84%E5%90%8D%E5%AD%97%E5%8F%AB%EF%BC%9A%CF%80%E6%A1%86%E6%9E%B6%20-%20PhalApi%202016%E5%B9%B4%E5%BA%A6%E5%BC%80%E6%BA%90%E6%80%BB%E7%BB%93%20-%20%E5%AE%98%E6%96%B9%E5%87%BA%E5%93%81.pdf" target="blank"><img width="950" height="100" src="http://7xiz2f.com1.z0.glb.clouddn.com/ad_20170104.png"></a>
		<a href="http://www.itran.cc/" target="blank"><img width="950" height="100" src="http://7xslqv.com1.z0.glb.clouddn.com/images/9/69/b88bc92455dc1239f9a5bf8d72929.png"></a>
		<a href="http://web-tools.phalapi.net/" target="blank"><img width="950" height="100" src="http://7xslqv.com1.z0.glb.clouddn.com/images/7/d0/88f523566c482296aecc43d185ca2.png"></a>
	</p>
</div>

        <!-- footer -->
        <div class="footer">
            <div class="link container ">
                <div class=" col-xs-7 col-sm-7 col-md-7 col-lg-7 ">
                    <h3>PhalApi (π框架)</h3>
                    <p>一个轻量级PHP开源接口框架，专注于接口服务开发，支持HTTP/SOAP/RPC协议，拥有自动生成的在线文档、多种开发语言的客户端SDK包以及可重用的扩展类库，可用于快速搭建微服务、RESTful接口或Web
                        Services。</p>
                    <!-- <p>:</p> -->
                    <span>友情链接:</span>
                    <a href="https://www.phalapi.net/" target="_blank"> PhalApi </a>
                    <a href="http://www.oschina.net/" target="_blank"> 开源中国 </a>
                    <a href="https://www.itran.cc/" target="_blank">艾翻译</a>
                    <a href="http://www.phalconphp.com/en/" target="_blank">Phalcon</a>
                    <a href="https://phpunit.de/manual/3.7/zh_cn/automating-tests.html" target="_blank">PHPUnit</a>
                    <a href="http://www.thoughtworks.com/cn/" target="_blank">ThoughtWorks</a>
                    <a href="mailto:chanzonghuang@gmail.com">友链交换</a>

                </div>
                <div class=" col-xs-5 col-sm-5 col-md-5 col-lg-5 contact_us ">
                    <h3>联系我们</h3>
                    <a href="https://github.com/phalapi/phalapi"><img src="../images/github.png" alt="github" /></a>
                    <a href="http://weibo.com/p/100808d236e99beb645bfb56ed1c37dde9b8bd?k=phalapi%E5%BC%80%E6%BA%90%E6%A1%86%E6%9E%B6&from=501&_from_=huati_topic"><img src="../images/weibo.png"  alt="weibo" /></a>
                    <a href="http://7xslqv.com1.z0.glb.clouddn.com/images/1/b0/894fde762850cb11250253f7d5ede.png"><img src="../images/zfb.png"  alt="zfb" /></a>
                    <a href="https://jq.qq.com/?_wv=1027&k=4A6reum"><img src="../images/qq.png"  alt="qq" /></a>
					<a href="http://git.oschina.net/dogstar/PhalApi"><img src="../images/git-oschina.png"  alt="git-oschina" /></a>
                </div>
                <div class="cls"></div>
                <div class="text-center copy_right"> ©2015-2017 PhalApi All Rights Reserved. <a href="http://www.miitbeian.gov.cn" target="_blank">粤ICP备15028808号</a>

				<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1255326144'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s4.cnzz.com/z_stat.php%3Fid%3D1255326144%26show%3Dpic' type='text/javascript'%3E%3C/script%3E"));</script>
                </div>
            </div>
        </div>
    </div>


    <a href="https://github.com/phalapi"><img id="gitHub_fllow" style="position: fixed; top: 0; right: 0; border: 0;z-index:9999" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a>


    <script src="../js/jquery-1.11.1.min.js"></script>
    <script src="../js/bootstrap.min.js"></script>
</body>

</html>